home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1997-2002 Alias|Wavefront,
- // a division of Silicon Graphics Limited.
- //
- // The information in this file is provided for the exclusive use of the
- // licensees of Alias|Wavefront. Such users have the right to use, modify,
- // and incorporate this code into other products for purposes authorized
- // by the Alias|Wavefront license agreement, without fee.
- //
- // ALIAS|WAVEFRONT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- // EVENT SHALL ALIAS|WAVEFRONT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- //
- //
- // Alias|Wavefront Script File
- // MODIFY THIS AT YOUR OWN RISK
- //
- //
- // Creation Date: 2003
- // Author: Duncan Brinsmead
- //
- //<doc>
- //<name createMotionField>
- //<owner "Alias|Wavefront Unsupported">
- //
- //<synopsis>
- // createMotionField
- //
- //<returns>
- // None.
- //
- //<description>
- // This command creates a force that pushes a fluid based on the motion
- // of an object. One selects the objects that one wishes to push the fluid
- // with and the fluids one wishes to affect. At least one fluid and one
- // non-fluid must be selected. One will not see an effect until the object
- // is animated. MakeFluidPusher creates a force for each object and sizes the
- // volume boundary of the force to be a bit larger than the object. An
- // expression is generated that sets the direction and magnitude of the
- // force based on the current motion of the object. The attribute
- // "pushIntensity" is added to the force node under extra attributes.
- // This allows one to adjust the magnitude of the push force.
- // Note that if one also does a fluid->makeCollide on the object that the
- // pushIntensity may need to be increased, as the force evaluates to zero
- // in the colliding regions of the fluid. This is one reason why
- // the force bounds to be larger than the object size.
- // Adjusting the scale and volume shape of the force can help to achieve
- // the best effect.
- //
- //<flags>
- // None.
- //
- //<examples>
- // // Create a fluid with emitter
- // Create2DContainerEmitter;
- // // Create an animated sphere
- // sphere;
- // move -r 3 3 0;
- // setKeyframe;
- // currentTime 100;
- // move -r -6 -6 0;
- // setKeyframe;
- // select -r fluidShape1 nurbsSphere1;
- // createMotionField;
- //</doc>
-
-
- global proc createMotionField()
- {
- float $pushIntensity = 10.0;
- float $flOverScale = 1.6/2.0;
- float $maxAspect = 0.1;
-
- string $fluids[] = `ls -sl -dag -type fluidShape`;
- string $selObjs[] = `ls -sl -type transform`;
- string $objs[];
- int $numObjs=0;
- int $i;
- for( $i = 0; $i < size($selObjs); $i++ ){
- string $fls[] = `ls -dag -type fluidShape $selObjs[$i]`;
- if( 0 == size( $fls )){
- $objs[$numObjs] = $selObjs[$i];
- $numObjs++;
- }
- }
- if( $numObjs == 0 || size($fluids) == 0 ){
- warning ("createMotionField needs at least one fluid and one object to be selected");
- return;
- }
- string $fields[];
- int $numFields =0;
- for( $i = 0; $i < $numObjs; $i++ ){
- select -r $fluids;
- Uniform;
- $selObjs = `ls -sl`;
- string $field = $selObjs[0];
- $field = `rename $field "motionField#"`;
- $fields[ $numFields ] = $field;
- $numFields++;
- setAttr ($field + ".attenuation") .1;
- setAttr ($field + ".volumeShape") 2;
-
- string $obj = $objs[$i];
- float $bbox[] = `exactWorldBoundingBox $obj`;
- $min[0] = $bbox[0];
- $min[1] = $bbox[1];
- $min[2] = $bbox[2];
- $max[0] = $bbox[3];
- $max[1] = $bbox[4];
- $max[2] = $bbox[5];
-
- float $fsx =$flOverScale *( $max[0] - $min[0] );
- float $fsy =$flOverScale *( $max[1] - $min[1] );
- float $fsz =$flOverScale *( $max[2] - $min[2] );
-
-
- float $maxScale = $fsx;
- if( $maxScale < $fsy ){
- $maxScale = $fsy;
- }
- if( $maxScale < $fsz ){
- $maxScale = $fsz;
- }
- $maxScale *= $maxAspect;
- // avoid flat forces
- if( $fsx < $maxScale ) {
- $fsx = $maxScale;
- }
- if( $fsy < $maxScale ){
- $fsy = $maxScale;
- }
- if( $fsz < $maxScale ){
- $fsz = $maxScale;
- }
-
- setAttr ($field + ".tx") ($min[0] + 0.5 * ($max[0]-$min[0]));
- setAttr ($field + ".ty") ($min[1] + 0.5 * ($max[1]-$min[1]));
- setAttr ($field + ".tz") ($min[2] + 0.5 * ($max[2]-$min[2]));
- setAttr ($field + ".sx") $fsx;
- setAttr ($field + ".sy") $fsy;
- setAttr ($field + ".sz") $fsz;
- parent $field $obj;
-
- addAttr -ln pushIntensity -sn pi -at double -min -0 -max 100 -dv $pushIntensity $field;
- setAttr -e -keyable true ($field + ".pushIntensity");
- string $exp = (
- "float $x = "+$obj+".translateX;\n"
- +"float $y = "+$obj+".translateY;\n"
- +"float $z = "+$obj+".translateZ;\n"
- +"float $to[3] = `getAttr -time (frame - 1.5) "
- + $obj + ".translate`;\n"
- +"$x -= $to[0];\n"
- +"$y -= $to[1];\n"
- +"$z -= $to[2];\n"
- +"float $len = sqrt( $x*$x + $y*$y + $z*$z );\n"
- +"if( $len > 0.00001 ){\n"
- +" $x /= $len;\n"
- +" $y /= $len;\n"
- +" $z /= $len;\n"
- +"}\n"
- + $field + ".directionX = $x;\n"
- + $field + ".directionY = $y;\n"
- + $field + ".directionZ = $z;\n"
- + $field + ".magnitude = "+$field+".pushIntensity * $len*20;\n"
- );
- expression -s $exp;
-
- }
- select -r $fields;
-
- }
-